home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 3006 / 3006.xpi / components / dhUtilService.js < prev    next >
Text File  |  2010-01-15  |  38KB  |  1,246 lines

  1. /******************************************************************************
  2.  *            Copyright (c) 2006-2009 Michel Gutierrez. All Rights Reserved.
  3.  ******************************************************************************/
  4.  
  5. /**
  6. * @fileoverview Accessing global utilities
  7. * @author mig
  8. * @version 1.0
  9. */
  10.  
  11. /**
  12.  * Constants.
  13.  */
  14. const NS_UTIL_SERVICE_CID = Components.ID("{dbd8dc72-2cdf-44ad-bf9a-5dc7a3fc3036}");
  15. const NS_UTIL_SERVICE_PROG_ID = "@downloadhelper.net/util-service;1";
  16.  
  17. Node=null;
  18. XPathResult=null;
  19.  
  20. /**
  21. * Service constructor
  22. * @class Service accessing global utilities
  23. */
  24. function UtilService() {
  25.     this.stringBundle=Components.classes["@mozilla.org/intl/stringbundle;1"].getService().
  26.         QueryInterface(Components.interfaces.nsIStringBundleService).
  27.             createBundle("chrome://dwhelper/locale/strings.properties");
  28.     this.RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService().
  29.         QueryInterface(Components.interfaces.nsIRDFService);
  30.     this.RDFCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].getService().
  31.         QueryInterface(Components.interfaces.nsIRDFContainerUtils);
  32. }
  33.  
  34. UtilService.prototype = {
  35. }
  36.  
  37. UtilService.prototype.getRDF = function() {
  38.     return this.RDF;
  39. }
  40.  
  41. UtilService.prototype.getRDFCUtils = function() {
  42.     return this.RDFCUtils;
  43. }
  44.  
  45. UtilService.prototype.getText = function(name) {
  46.     try {
  47.         return this.stringBundle.GetStringFromName(name);
  48.     } catch(e) {
  49.         return name;
  50.     }
  51. }
  52.  
  53. UtilService.prototype.getFText=function(name,params,length) {
  54.     if(params==null)
  55.         params=[];
  56.     try {
  57.         return this.stringBundle.formatStringFromName(name,params,params.length);
  58.     } catch(e) {
  59.         return name;
  60.     }
  61. }
  62.  
  63. UtilService.prototype.getVersion=function(uuid) {
  64.     var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService().
  65.         QueryInterface(Components.interfaces.nsIRDFService);
  66.     var RDFCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].getService().
  67.         QueryInterface(Components.interfaces.nsIRDFContainerUtils);
  68.     var extMgr=Components.classes["@mozilla.org/extensions/manager;1"].
  69.         getService(Components.interfaces.nsIExtensionManager);        
  70.     var target=extMgr.datasource.GetTarget(
  71.         RDF.GetResource("urn:mozilla:item:"+uuid),
  72.         RDF.GetResource("http://www.mozilla.org/2004/em-rdf#version"),
  73.         true);
  74.     if(target==null)
  75.         return null;
  76.     return target.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  77. }
  78.  
  79. UtilService.prototype.getPropertyValue = function(ds,res,prop) {
  80.     var target=ds.GetTarget(res,prop,true);
  81.     if(target==null)
  82.         return null;
  83.     return target.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
  84. }
  85.  
  86. UtilService.prototype.getPropertyValueRS = function(ds,res,prop) {
  87.     return this.getPropertyValue(ds,res,this.RDF.GetResource(prop));
  88. }
  89.  
  90. UtilService.prototype.getPropertyValueSR = function(ds,res,prop) {
  91.     return this.getPropertyValue(ds,this.RDF.GetResource(res),prop);
  92. }
  93.  
  94. UtilService.prototype.getPropertyValueSS = function(ds,res,prop) {
  95.     return this.getPropertyValue(ds,this.RDF.GetResource(res),this.RDF.GetResource(prop));
  96. }
  97.  
  98. UtilService.prototype.setPropertyValue = function(ds,res,prop,value) {
  99.     value=this.RDF.GetLiteral(value);
  100.     this.removeProperties(ds,res,prop);
  101.     if(value!=null) {
  102.         ds.Assert(res,prop,value,true);
  103.     }
  104. }
  105.  
  106. UtilService.prototype.setPropertyValueSR = function(ds,res,prop,value) {
  107.     this.setPropertyValue(ds,this.RDF.GetResource(res),prop,value);
  108. }
  109.  
  110. UtilService.prototype.setPropertyValueRS = function(ds,res,prop,value) {
  111.     this.setPropertyValue(ds,res,this.RDF.GetResource(prop),value);
  112. }
  113.  
  114. UtilService.prototype.setPropertyValueSS = function(ds,res,prop,value) {
  115.     this.setPropertyValue(ds,this.RDF.GetResource(res),this.RDF.GetResource(prop),value);
  116. }
  117.  
  118. UtilService.prototype.removeProperties = function(ds,res,prop) {
  119.     var i=ds.GetTargets(res,prop,true);
  120.     var targets=[];
  121.     while(i.hasMoreElements()) {
  122.         targets.push(i.getNext());
  123.     }
  124.     for(var i=0;i<targets.length;i++) {
  125.         ds.Unassert(res,prop,targets[i]);
  126.     }
  127. }
  128.  
  129. UtilService.prototype.removePropertiesSR = function(ds,res,prop) {
  130.     this.removeProperties(ds,this.RDF.GetResource(res),prop);
  131. }
  132.  
  133. UtilService.prototype.removePropertiesRS = function(ds,res,prop) {
  134.     this.removeProperties(ds,res,this.RDF.GetResource(prop));
  135. }
  136.  
  137. UtilService.prototype.removePropertiesSS = function(ds,res,prop) {
  138.     this.removeProperties(ds,this.RDF.GetResource(res),this.RDF.GetResource(prop));
  139. }
  140.  
  141. UtilService.prototype.getChildResources = function(ds,res,count) {
  142.     var children=[];
  143.     var seq=this.RDFCUtils.MakeSeq(ds,res);
  144.     var j=seq.GetElements();
  145.     while(j.hasMoreElements()) {
  146.         var li=j.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  147.         children.push(li);
  148.     }
  149.     count.value=children.length;
  150.     return children;
  151. }
  152.  
  153. UtilService.prototype.getChildResourcesS = function(ds,res,count) {
  154.     return this.getChildResources(ds,this.RDF.GetResource(res),count);
  155. }
  156.  
  157. UtilService.prototype.getPropertyResource = function(ds,res,prop) {
  158.     var target=ds.GetTarget(res,prop,true);
  159.     if(target==null)
  160.         return null;
  161.     return target.QueryInterface(Components.interfaces.nsIRDFResource);
  162. }
  163.  
  164. UtilService.prototype.getPropertyResourceRS = function(ds,res,prop) {
  165.     return this.getPropertyResource(ds,res,this.RDF.GetResource(prop));
  166. }
  167.  
  168. UtilService.prototype.getPropertyResourceSR = function(ds,res,prop) {
  169.     return this.getPropertyResource(ds,this.RDF.GetResource(res),prop);
  170. }
  171.  
  172. UtilService.prototype.getPropertyResourceSS = function(ds,res,prop) {
  173.     return this.getPropertyResource(ds,this.RDF.GetResource(res),this.RDF.GetResource(prop));
  174. }
  175.  
  176. UtilService.prototype.setPropertyResource = function(ds,res,prop,value) {
  177.     this.removeProperties(ds,res,prop);
  178.     if(value!=null) {
  179.         ds.Assert(res,prop,value,true);
  180.     }
  181. }
  182.  
  183. UtilService.prototype.setPropertyResourceRRS = function(ds,res,prop,value) {
  184.     this.setPropertyResource(ds,res,prop,this.RDF.GetResource(value));
  185. }
  186.  
  187. UtilService.prototype.setPropertyResourceRSR = function(ds,res,prop,value) {
  188.     this.setPropertyResource(ds,res,this.RDF.GetResource(prop),value);
  189. }
  190.  
  191. UtilService.prototype.setPropertyResourceRSS = function(ds,res,prop,value) {
  192.     this.setPropertyResource(ds,res,this.RDF.GetResource(prop),this.RDF.GetResource(value));
  193. }
  194.  
  195. UtilService.prototype.setPropertyResourceSRR = function(ds,res,prop,value) {
  196.     this.setPropertyResource(ds,this.RDF.GetResource(res),prop,value);
  197. }
  198.  
  199. UtilService.prototype.setPropertyResourceSRS = function(ds,res,prop,value) {
  200.     this.setPropertyResource(ds,this.RDF.GetResource(res),prop,this.RDF.GetResource(value));
  201. }
  202.  
  203. UtilService.prototype.setPropertyResourceSSR = function(ds,res,prop,value) {
  204.     this.setPropertyResource(ds,this.RDF.GetResource(res),this.RDF.GetResource(prop),value);
  205. }
  206.  
  207. UtilService.prototype.setPropertyResourceSSS = function(ds,res,prop,value) {
  208.     this.setPropertyResource(ds,this.RDF.GetResource(res),this.RDF.GetResource(prop),this.RDF.GetResource(value));
  209. }
  210.  
  211. UtilService.prototype.createNode=function(ds,parentNode,res) {
  212.     var node=res;
  213.     if(node==null) {
  214.         node=this.RDF.GetAnonymousResource();
  215.     } 
  216.     this.setPropertyResourceRSS(ds,node,
  217.         "http://www.w3.org/1999/02/22-rdf-syntax-ns#instanceOf",
  218.         "http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq");
  219.     this.setPropertyValueRS(ds,node,
  220.         "http://www.w3.org/1999/02/22-rdf-syntax-ns#nextVal","1");
  221.     
  222.     if(parentNode!=null) {
  223.         parentNode=this.RDFCUtils.MakeSeq(ds,parentNode);
  224.         parentNode.AppendElement(node);
  225.     } 
  226.     return node;
  227. }
  228.  
  229. UtilService.prototype.createNodeRS=function(ds,parentNode,resValue) {
  230.     if(resValue!=null)
  231.         resValue=this.RDF.GetResource(resValue);
  232.     return this.createNode(ds,parentNode,resValue);
  233. }
  234.  
  235. UtilService.prototype.createNodeSR=function(ds,parentNode,resValue) {
  236.     if(parentNode!=null)
  237.         parentNode=this.RDF.GetResource(parentNode);
  238.     return this.createNode(ds,parentNode,resValue);
  239. }
  240.  
  241. UtilService.prototype.createNodeSS=function(ds,parentNode,resValue) {
  242.     if(parentNode!=null)
  243.         parentNode=this.RDF.GetResource(parentNode);
  244.     if(resValue!=null)
  245.         resValue=this.RDF.GetResource(resValue);
  246.     return this.createNode(ds,parentNode,resValue);
  247. }
  248.  
  249. UtilService.prototype.createAnonymousNode=function(ds,parentNode) {
  250.     return this.createNode(ds,parentNode,null);
  251. }
  252.  
  253. UtilService.prototype.createAnonymousNodeS=function(ds,parentNode) {
  254.     return this.createAnonymousNode(ds,this.RDF.GetResource(parentNode));
  255. }
  256.  
  257. UtilService.prototype.createRootNode=function(ds,res) {
  258.     return this.createNode(ds,null,res);
  259. }
  260.  
  261. UtilService.prototype.createRootNodeS=function(ds,resValue) {
  262.     return this.createRootNode(ds,this.RDF.GetResource(resValue));
  263. }
  264.  
  265. UtilService.prototype.createAnonymousRootNode=function(ds) {
  266.     return this.createNode(ds,null,null);
  267. }
  268.  
  269. UtilService.prototype.getDatasourceFromRDFFile=function(file) {
  270.  
  271.     var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
  272.         createInstance(Components.interfaces.nsIFileInputStream);
  273.     fis.init(file,1,0,false);
  274.     
  275.     var charset = "UTF-8";
  276.     const replacementChar = Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER;
  277.     var is = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
  278.                        .createInstance(Components.interfaces.nsIConverterInputStream);
  279.     is.init(fis, charset, 1024, replacementChar);
  280.     
  281.     var fileContents="";
  282.     var str = {};
  283.     while (is.readString(4096, str) != 0) {
  284.       fileContents+=str.value;
  285.     }
  286.  
  287.     is.close();
  288.     fis.close();
  289.     
  290.     var parser=Components.classes
  291.               ['@mozilla.org/rdf/xml-parser;1'].
  292.                   createInstance(Components.interfaces.nsIRDFXMLParser);
  293.     var uri = Components.classes["@mozilla.org/network/standard-url;1"].
  294.                 createInstance(Components.interfaces.nsIURI);
  295.     uri.spec = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
  296.     var memDS=Components.classes
  297.               ['@mozilla.org/rdf/datasource;1?name=in-memory-datasource'].
  298.                   createInstance(Components.interfaces.nsIRDFDataSource);
  299.     parser.parseString(memDS,uri,fileContents);
  300.     return memDS;
  301. }
  302.  
  303. UtilService.prototype.dumpDatasource=function(ds) {
  304.     if(ds==null)
  305.         return;
  306.     var i = ds.GetAllResources();
  307.     while(i.hasMoreElements()) {
  308.         var source = i.getNext();
  309.         var j = ds.ArcLabelsOut(source);
  310.         while(j.hasMoreElements()) {
  311.             var predicate = j.getNext();
  312.             var k = ds.GetTargets(source,predicate,true);
  313.             while(k.hasMoreElements()) {
  314.                 var target = k.getNext();
  315.                 source=source.QueryInterface(Components.interfaces.nsIRDFResource);
  316.                 predicate=predicate.QueryInterface(Components.interfaces.nsIRDFResource);
  317.                 try {
  318.                     target=target.QueryInterface(Components.interfaces.nsIRDFResource);
  319.                 } catch(e) {
  320.                     target=target.QueryInterface(Components.interfaces.nsIRDFLiteral);
  321.                 }
  322.                 dump(source.Value+" - "+predicate.Value+" - "+target.Value+"\n");
  323.             }
  324.         }
  325.     }
  326. }
  327.  
  328. UtilService.prototype.exceptionDesc=function(e) {
  329.     e=e.QueryInterface(Components.interfaces.nsIException);
  330.     return e.message+" "+e.filename+":"+e.lineNumber;
  331. }
  332.  
  333. UtilService.prototype.getDatasource=function(tree) {
  334.     if(tree.database==null)
  335.         return null;
  336.     var i=tree.database.GetDataSources();
  337.     if(i.hasMoreElements()) {
  338.         return i.getNext().QueryInterface(Components.interfaces.nsIRDFDataSource);
  339.     } else {
  340.         return null;
  341.     }
  342. }
  343.  
  344. UtilService.prototype.clearDatasource=function(tree) {
  345.     if(tree.database==null)
  346.         return;
  347.     var dss=[];
  348.     var i=tree.database.GetDataSources();
  349.     while(i.hasMoreElements()) {
  350.         dss.push(i.getNext());
  351.     }
  352.     for(var i=0;i<dss.length;i++) {
  353.         var ds = dss[i].QueryInterface(Components.interfaces.nsIRDFDataSource);
  354.         var i = ds.GetAllResources();
  355.         ds.beginUpdateBatch();
  356.         while(i.hasMoreElements()) {
  357.             var source = i.getNext();
  358.             var j = ds.ArcLabelsOut(source);
  359.             while(j.hasMoreElements()) {
  360.                 var predicate = j.getNext();
  361.                 var k = ds.GetTargets(source,predicate,true);
  362.                 while(k.hasMoreElements()) {
  363.                     var target = k.getNext();
  364.                     ds.Unassert(source,predicate,target);
  365.                 }
  366.             }
  367.         }
  368.         ds.endUpdateBatch();
  369.     }
  370.     for(var i=0;i<dss.length;i++) {
  371.         var ds = dss[i].QueryInterface(Components.interfaces.nsIRDFDataSource);
  372.         tree.database.RemoveDataSource(ds);
  373.     }
  374. }
  375.  
  376. UtilService.prototype.emptyDatasource=function(ds) {
  377.     var i = ds.GetAllResources();
  378.     ds.beginUpdateBatch();
  379.     while(i.hasMoreElements()) {
  380.         var source = i.getNext();
  381.         var j = ds.ArcLabelsOut(source);
  382.         while(j.hasMoreElements()) {
  383.             var predicate = j.getNext();
  384.             var k = ds.GetTargets(source,predicate,true);
  385.             while(k.hasMoreElements()) {
  386.                 var target = k.getNext();
  387.                 ds.Unassert(source,predicate,target);
  388.             }
  389.         }
  390.     }
  391.     ds.endUpdateBatch();
  392. }
  393.  
  394. UtilService.prototype.removeDatasources=function(tree) {
  395.     if(tree.database==null)
  396.         return;
  397.     var dss=[];
  398.     var i=tree.builder.database.GetDataSources();
  399.     while(i.hasMoreElements()) {
  400.         dss.push(i.getNext());
  401.     }
  402.     for(var i=0;i<dss.length;i++) {
  403.         var ds = dss[i].QueryInterface(Components.interfaces.nsIRDFDataSource);
  404.         tree.builder.database.RemoveDataSource(ds);
  405.     }
  406. }
  407.  
  408. UtilService.prototype.setDatasource=function(tree,ds) {
  409.     this.removeDatasources(tree);
  410.     if(ds!=null)
  411.         tree.builder.database.AddDataSource(ds);
  412.     tree.builder.rebuild();
  413. }
  414.  
  415. UtilService.prototype.addDatasource=function(tree,ds) {
  416.     if(ds!=null)
  417.         tree.builder.database.AddDataSource(ds);
  418.     tree.builder.rebuild();
  419. }
  420.  
  421. UtilService.prototype.copyDatasource=function(ds) {
  422.     var memDS=Components.classes
  423.             ['@mozilla.org/rdf/datasource;1?name=in-memory-datasource'].
  424.                 createInstance(Components.interfaces.nsIRDFDataSource);
  425.     var i = ds.GetAllResources();
  426.     memDS.beginUpdateBatch();
  427.     while(i.hasMoreElements()) {
  428.         var source = i.getNext();
  429.         var j = ds.ArcLabelsOut(source);
  430.         while(j.hasMoreElements()) {
  431.             var predicate = j.getNext();
  432.             var k = ds.GetTargets(source,predicate,true);
  433.             while(k.hasMoreElements()) {
  434.                 var target = k.getNext();
  435.                 memDS.Assert(source,predicate,target,true);
  436.             }
  437.         }
  438.     }
  439.     memDS.endUpdateBatch();
  440.     
  441.     return memDS;
  442. }
  443.  
  444. UtilService.prototype.concatDatasource=function(ds0,ds) {
  445.     var i = ds.GetAllResources();
  446.     ds0.beginUpdateBatch();
  447.     while(i.hasMoreElements()) {
  448.         var source = i.getNext();
  449.         var j = ds.ArcLabelsOut(source);
  450.         while(j.hasMoreElements()) {
  451.             var predicate = j.getNext();
  452.             var k = ds.GetTargets(source,predicate,true);
  453.             while(k.hasMoreElements()) {
  454.                 var target = k.getNext();
  455.                 ds0.Assert(source,predicate,target,true);
  456.             }
  457.         }
  458.     }
  459.     ds0.endUpdateBatch();
  460. }
  461.  
  462. UtilService.prototype.getParentNode=function(ds,node) {
  463.     var iter=ds.ArcLabelsIn(node);
  464.     while(iter.hasMoreElements()) {
  465.         var arc=iter.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  466.         if(ChartletUtil.startsWith(arc.Value,"http://www.w3.org/1999/02/22-rdf-syntax-ns#_")) {
  467.                node = ds.GetSource(arc,node,true);
  468.                return node;
  469.         }
  470.     }
  471.     return null;
  472. }
  473.  
  474. UtilService.prototype.getParentNodeS=function(ds,node) {
  475.     return this.getParentNode(ds,this.RDF.GetResource(node));
  476. }
  477.  
  478. UtilService.prototype.appendNode=function(ds,parentNode,node) {
  479.     parentNode=this.RDFCUtils.MakeSeq(ds,parentNode);
  480.     parentNode.AppendElement(node);
  481. }
  482.  
  483. UtilService.prototype.appendNodeRS=function(ds,parentNode,node) {
  484.     this.appendNode(ds,parentNode,this.RDF.GetResource(node));
  485. }
  486.  
  487. UtilService.prototype.appendNodeSR=function(ds,parentNode,node) {
  488.     this.appendNode(ds,this.RDF.GetResource(parentNode),node);
  489. }
  490.  
  491. UtilService.prototype.appendNodeSS=function(ds,parentNode,node) {
  492.     this.appendNode(ds,this.RDF.GetResource(parentNode),this.RDF.GetResource(node));
  493. }
  494.  
  495. UtilService.prototype.removeReference = function(ds,res) {
  496.     var seqElems=[];
  497.     
  498.     var deltriplet=[];
  499.     var i=ds.ArcLabelsIn(res);
  500.     while(i.hasMoreElements()) {
  501.         var arc=i.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  502.         var j=ds.GetSources(arc,res,true);
  503.         while(j.hasMoreElements()) {
  504.             var source=j.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  505.             var m=/^http\:\/\/www\.w3\.org\/1999\/02\/22\-rdf\-syntax\-ns#_([1-9][0-9]*)$/.exec(arc.Value);
  506.             if(m.length==2) {
  507.                 var seq=ChartletUtil.RDFCUtils.MakeSeq(ds,source);
  508.                 seqElems.push({seq: seq, elem: res});            
  509.             } else {
  510.                 deltriplet.push({
  511.                     source: source,
  512.                     property: arc,
  513.                     target: res
  514.                 });
  515.             }
  516.         }
  517.     }
  518.     
  519.     var i=ds.ArcLabelsOut(res);
  520.     while(i.hasMoreElements()) {
  521.         var arc=i.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  522.         var j=ds.GetTargets(res,arc,true);
  523.         while(j.hasMoreElements()) {
  524.             var target=j.getNext().QueryInterface(Components.interfaces.nsIRDFNode);
  525.             deltriplet.push({
  526.                 source: res,
  527.                 property: arc,
  528.                 target: target
  529.                 });
  530.         }
  531.     }
  532.     
  533.     ds.beginUpdateBatch();
  534.     for(var i=0;i<deltriplet.length;i++) {
  535.         var triplet=deltriplet[i];
  536.         ds.Unassert(triplet.source,triplet.property,triplet.target);
  537.     }
  538.     for(var i=0;i<seqElems.length;i++) {
  539.         seqElems[i].seq.RemoveElement(seqElems[i].elem,true);
  540.     }
  541.     ds.endUpdateBatch();
  542. }
  543.  
  544. UtilService.prototype.removeReferenceS = function(ds,res) {
  545.     this.removeReference(ds,this.RDF.GetResource(res));
  546. }
  547.  
  548. UtilService.prototype.xpGetSingleNode = function(node,xpath) {
  549.     var anode=node.ownerDocument.evaluate(xpath,node,null,
  550.         XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
  551.     return anode;
  552. }
  553.  
  554. UtilService.prototype.xpGetNodes = function(node,xpath,count) {
  555.     var nodes=[];
  556.     var xpr=node.ownerDocument.evaluate(xpath,
  557.         node,null,
  558.         XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  559.         null);
  560.     var node0=xpr.iterateNext();
  561.     while(node0!=null) {
  562.         nodes.push(node0);
  563.         node0=xpr.iterateNext();
  564.     }
  565.     count.value=nodes.length;
  566.     return nodes;
  567. }
  568.  
  569. UtilService.prototype.xpGetStrings = function(node,xpath,count) {
  570.     var strings=[];
  571.     var xpr=node.ownerDocument.evaluate(xpath,
  572.         node,null,
  573.         XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  574.         null);
  575.     var lastTextNode=null;
  576.     var node0=xpr.iterateNext();
  577.     while(node0!=null) {
  578.         if(node0.nodeType==Node.TEXT_NODE) {
  579.             if(node0.previousSibling==lastTextNode) {
  580.                 var prevText=strings.pop();
  581.                 strings.push(prevText+node0.nodeValue);
  582.             } else {
  583.                 strings.push(node0.nodeValue);
  584.             }
  585.             lastTextNode=node0;
  586.         }
  587.         else if(node0.firstChild!=null && node0.firstChild.nodeType==Node.TEXT_NODE)
  588.             strings.push(node0.firstChild.nodeValue);
  589.         node0=xpr.iterateNext();
  590.     }
  591.     count.value=strings.length;
  592.     return strings;
  593. }
  594.  
  595. UtilService.prototype.xpGetString = function(node,xpath) {
  596.     var text=node.ownerDocument.evaluate(xpath,node,null,
  597.         XPathResult.STRING_TYPE,null).stringValue;
  598.     return text;
  599. }
  600.  
  601. UtilService.prototype.getProfileDir=function() {
  602.     var file = Components.classes["@mozilla.org/file/directory_service;1"]
  603.         .getService(Components.interfaces.nsIProperties)
  604.         .get("ProfD", Components.interfaces.nsIFile);
  605.     return file;
  606. }
  607.  
  608. UtilService.prototype.getProfilePath=function() {
  609.     return this.getProfileDir().path;
  610. }
  611.  
  612. UtilService.prototype.getExtensionDir=function(uuid) {
  613.     var file = this.getProfileDir();
  614.     file.append("extensions");
  615.     file.append(uuid);
  616.     return file;
  617. }
  618.  
  619. UtilService.prototype.getExtensionPath=function(uuid) {
  620.     return this.getExtensionDir(uuid).path;
  621. }
  622.  
  623. UtilService.prototype.removeReferenceS=function(ds,res) {
  624.     this.removeReference(ds,this.RDF.GetResource(res));
  625. }
  626.  
  627. UtilService.prototype.removeReference=function(ds,res) {
  628.  
  629.     var seqElems=[];
  630.     
  631.     var deltriplet=[];
  632.     var i=ds.ArcLabelsIn(res);
  633.     while(i.hasMoreElements()) {
  634.         var arc=i.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  635.         var j=ds.GetSources(arc,res,true);
  636.         while(j.hasMoreElements()) {
  637.             var source=j.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  638.             var m=/^http\:\/\/www\.w3\.org\/1999\/02\/22\-rdf\-syntax\-ns#_([1-9][0-9]*)$/.exec(arc.Value);
  639.             if(m.length==2) {
  640.                 var seq=this.RDFCUtils.MakeSeq(ds,source);
  641.                 seqElems.push({seq: seq, elem: res});            
  642.             } else {
  643.                 deltriplet.push({
  644.                     source: source,
  645.                     property: arc,
  646.                     target: res
  647.                 });
  648.             }
  649.         }
  650.     }
  651.     
  652.     var i=ds.ArcLabelsOut(res);
  653.     while(i.hasMoreElements()) {
  654.         var arc=i.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  655.         var j=ds.GetTargets(res,arc,true);
  656.         while(j.hasMoreElements()) {
  657.             var target=j.getNext().QueryInterface(Components.interfaces.nsIRDFNode);
  658.             deltriplet.push({
  659.                 source: res,
  660.                 property: arc,
  661.                 target: target
  662.                 });
  663.         }
  664.     }
  665.     
  666.     ds.beginUpdateBatch();
  667.     for(var i=0;i<deltriplet.length;i++) {
  668.         var triplet=deltriplet[i];
  669.         ds.Unassert(triplet.source,triplet.property,triplet.target);
  670.     }
  671.     for(var i=0;i<seqElems.length;i++) {
  672.         seqElems[i].seq.RemoveElement(seqElems[i].elem,true);
  673.     }
  674.     ds.endUpdateBatch();
  675. }
  676.  
  677. UtilService.prototype.generateUuid=function() {
  678.     var uuid="";
  679.     var groups=[8,4,4,4,12];
  680.     for(var i=0;i<groups.length;i++) {
  681.         if(i>0)
  682.             uuid+="-";
  683.         for(var j=0;j<groups[i];j++) {
  684.             var d=Math.floor(Math.random()*16);
  685.             if(d<10) {
  686.                 uuid+=String.fromCharCode("0".charCodeAt(0)+d);
  687.             } else {
  688.                 uuid+=String.fromCharCode("a".charCodeAt(0)-10+d);
  689.             }
  690.         }
  691.     }
  692.     return uuid;
  693. }
  694.  
  695. UtilService.prototype.generateXPath = function(node) {
  696.     var node0=node;
  697.     var str="";
  698.     while(node.parentNode!=null) {
  699.         var str0="/";
  700.         if(node.nodeType==Node.TEXT_NODE) {
  701.             str0+="text()";
  702.         } else {
  703.             str0+=node.nodeName.toLowerCase();
  704.         }
  705.         var index=this.getNodeChildIndex(node);
  706.         str0+="["+(index+1)+"]";
  707.         str=str0+str;
  708.         node=node.parentNode;
  709.     }
  710.     str=node.nodeName+str;
  711.     if(str.substr(0,9)=="#document")
  712.         str=str.substring(9);
  713.     return str;
  714. }
  715.  
  716. UtilService.prototype.getNodeChildIndex = function(child) {
  717.     var i=0;
  718.     var parent=child.parentNode;
  719.     var node=parent.firstChild;
  720.     while(node!=null) {
  721.         if(node==child)
  722.             return i;
  723.         if(node.nodeName==child.nodeName && 
  724.             (node.nodeType==Node.ELEMENT_NODE || node.nodeType==Node.TEXT_NODE))
  725.             i++;
  726.         node=node.nextSibling;
  727.     }
  728.     return -1;
  729. }
  730.  
  731. UtilService.prototype.decodeURL = function(text) {
  732.     var decoder=Components.classes["@mozilla.org/intl/utf8converterservice;1"]
  733.         .getService(Components.interfaces.nsIUTF8ConverterService);
  734.     text=decoder.convertURISpecToUTF8(text,null);
  735.     var hc="0123456789ABCDEFabcdef"; 
  736.     var pt="";
  737.     var i=0;
  738.     while (i < text.length) {
  739.         var ch=text.charAt(i);
  740.         if (ch=="+") {
  741.             pt+=" ";
  742.             i++;
  743.         } else if (ch=="%") {
  744.             if (i < (text.length-2) 
  745.                     && hc.indexOf(text.charAt(i+1)) != -1 
  746.                     && hc.indexOf(text.charAt(i+2)) != -1 ) {
  747.                 pt+=unescape( text.substr(i,3) );
  748.                 i+=3;
  749.             } else {
  750.                 pt+="?";
  751.                 i++;
  752.             }
  753.         } else {
  754.            pt+=ch;
  755.            i++;
  756.         }
  757.     } 
  758.    return pt;
  759. }
  760.  
  761. UtilService.prototype.encodeURL = function(text) {
  762.     var sc="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.!~*'()";
  763.     var h="0123456789ABCDEF";
  764.     var encoded="";
  765.     for (var i=0; i < text.length; i++ ) {
  766.         var ch=text.charAt(i);
  767.         if (ch==" ") {
  768.             encoded+="+";
  769.         } else if (sc.indexOf(ch) != -1) {
  770.             encoded+=ch;
  771.         } else {
  772.             var charCode=ch.charCodeAt(0);
  773.             if (charCode > 255) {
  774.                 encoded+="+";
  775.             } else {
  776.                 encoded+="%"+h.charAt((charCode >> 4) & 0xF)+h.charAt(charCode & 0xF);
  777.             }
  778.         }
  779.     }
  780.     return encoded;
  781. };
  782.  
  783. UtilService.prototype.contentPost = function(url,body,target,targetName,features) {
  784.     if(target==null) {
  785.         var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].getService().
  786.             QueryInterface(Components.interfaces.nsIWindowWatcher);
  787.         target=wwatch.openWindow(null, "about:blank",
  788.                      targetName, features, null);
  789.     }
  790.     var webNav = target.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
  791.         getInterface(Components.interfaces.nsIWebNavigation);
  792.     var sis = null;
  793.     if(body!=null) {
  794.         sis=Components.classes["@mozilla.org/io/string-input-stream;1"].
  795.             createInstance(Components.interfaces.nsIStringInputStream);
  796.         sis.setData("Content-length: "+body.length+"\r\n\r\n"+body,-1);
  797.     }
  798.     webNav.loadURI(url,webNav.LOAD_FLAGS_NONE,null,sis,null);
  799. }
  800.  
  801. UtilService.prototype.xmlEscape = function(str) {
  802.     str=str.replace(/&/g,"&");
  803.     str=str.replace(/</g,"<");
  804.     str=str.replace(/>/g,">");
  805.     //return str;
  806.     str=str.replace(/'/g,"'");
  807.     str=str.replace(/"/g,""");
  808.     return str;
  809.     var str0="";
  810.     for(var i=0;i<str.length;i++) {
  811.         var cc=str.charCodeAt(i);
  812.         if(cc>=0x80)
  813.             str0+="&#"+cc+";";
  814.         else
  815.             str0+=str[i];
  816.     }
  817.     return str0;
  818. }
  819.  
  820. UtilService.prototype.getUTCTime = function() {
  821.     var date=new Date();
  822.     var t=date.getTime();
  823.     t+=date.getTimezoneOffset()*60*1000;
  824.     return t;
  825. }
  826.  
  827. UtilService.prototype.formatNumberMinDigits = function(value,digits) {
  828.     var str=""+value;
  829.     while(str.length<digits)
  830.         str="0"+str;
  831.     return str;
  832. }
  833.  
  834. UtilService.prototype.getExceptionStack = function(e) {
  835.     try {
  836.         var msg="";
  837.         var location=e.location;
  838.         while(location!=null) {
  839.             msg+=location.filename+":"+location.lineNumber+"\n";
  840.             location=location.caller;
  841.         }
  842.         return msg;
  843.     } catch(e0) {
  844.         return "[UtilService] error while getting exception frame: "+e0;
  845.     }
  846. }
  847.  
  848. UtilService.prototype.removeChild = function(ds,parent,child) {
  849.     var seq=this.RDFCUtils.MakeSeq(ds,parent);
  850.     seq.RemoveElement(child,true);
  851. }
  852.  
  853. UtilService.prototype.removeChildRS = function(ds,parent,child) {
  854.     var seq=this.RDFCUtils.MakeSeq(ds,parent);
  855.     seq.RemoveElement(this.RDF.GetResource(child),true);
  856. }
  857.  
  858. UtilService.prototype.removeChildSR = function(ds,parent,child) {
  859.     var seq=this.RDFCUtils.MakeSeq(ds,this.RDF.GetResource(parent));
  860.     seq.RemoveElement(child,true);
  861. }
  862.  
  863. UtilService.prototype.removeChildSS = function(ds,parent,child) {
  864.     var seq=this.RDFCUtils.MakeSeq(ds,this.RDF.GetResource(parent));
  865.     seq.RemoveElement(this.RDF.GetResource(child),true);
  866. }
  867.  
  868. UtilService.prototype.getRDFNodeValue = function(node) {
  869.     if(node==null)
  870.         return null;
  871.     try {
  872.         var res=node.QueryInterface(Components.interfaces.nsIRDFResource);
  873.         return res.Value;
  874.     } catch(e) {}
  875.     try {
  876.         var lit=node.QueryInterface(Components.interfaces.nsIRDFLiteral);
  877.         return lit.Value;
  878.     } catch(e) {}
  879.     return null;
  880. }
  881.  
  882. UtilService.prototype.getUnicharPref = function(pref, prefName, defValue) {
  883.     //dump("getUnicharPref("+prefName+"): default="+defValue+"\n");
  884.     var value=defValue;
  885.     try {
  886.         value=pref.getComplexValue(prefName,Components.interfaces.nsISupportsString).data;
  887.     } catch(e) {}
  888.     //dump("getUnicharPref("+prefName+")=>"+value+"\n");
  889.     return value;
  890. }
  891.  
  892. UtilService.prototype.setUnicharPref = function(pref, prefName, value) {
  893.     //dump("setUnicharPref("+prefName+"): value="+value+"\n");
  894.     var str = Components.classes["@mozilla.org/supports-string;1"].
  895.         createInstance(Components.interfaces.nsISupportsString);
  896.     str.data = value; 
  897.     pref.setComplexValue(prefName,Components.interfaces.nsISupportsString,str);
  898.     //dump("setUnicharPref("+prefName+"): done - check="+this.getUnicharPref(pref,prefName,null)+"\n");
  899. }
  900.  
  901. UtilService.prototype.getStringSupport = function(str) {
  902.     var strSupport=Components.classes["@mozilla.org/supports-string;1"].
  903.         createInstance(Components.interfaces.nsISupportsString);
  904.     strSupport.data=str;
  905.     return strSupport;
  906. }
  907.  
  908. UtilService.prototype.setPropsString = function(props, key, value) {
  909.     var strSupport=Components.classes["@mozilla.org/supports-string;1"].
  910.         createInstance(Components.interfaces.nsISupportsString);
  911.     strSupport.data=value;
  912.     props.set(key,strSupport);
  913. }
  914.  
  915. UtilService.prototype.getPropsString = function(props, key) {
  916.     try {
  917.         var value=props.get(key,Components.interfaces.nsISupportsString);
  918.         if(value)
  919.             return value.toString();
  920.     } catch(e) {}
  921.     return null;
  922. }
  923.  
  924. UtilService.prototype.alert = function(message,title) {
  925.     var promptService=Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  926.     promptService.alert(null,title,message);
  927. }
  928.  
  929. UtilService.prototype.alertError = function(message) {
  930.     this.alert(message,this.getText("alert.title.error"));
  931. }
  932.  
  933. UtilService.prototype.alertWarning = function(message) {
  934.     this.alert(message,this.getText("alert.title.warning"));
  935. }
  936.  
  937. var Base64 = {
  938.         // private property
  939.         _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  940.         // public method for encoding
  941.         encode : function (input) {
  942.             var output = "";
  943.             var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  944.             var i = 0;
  945.             input = Base64._utf8_encode(input);
  946.             while (i < input.length) {
  947.                 chr1 = input.charCodeAt(i++);
  948.                 chr2 = input.charCodeAt(i++);
  949.                 chr3 = input.charCodeAt(i++);
  950.                 enc1 = chr1 >> 2;
  951.                 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  952.                 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  953.                 enc4 = chr3 & 63;
  954.                 if (isNaN(chr2)) {
  955.                     enc3 = enc4 = 64;
  956.                 } else if (isNaN(chr3)) {
  957.                     enc4 = 64;
  958.                 }
  959.                 output = output +
  960.                 this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
  961.                 this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
  962.             }
  963.             return output;
  964.         },
  965.      
  966.         // public method for decoding
  967.         decode : function (input) {
  968.             var output = "";
  969.             var chr1, chr2, chr3;
  970.             var enc1, enc2, enc3, enc4;
  971.             var i = 0;
  972.             input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  973.             while (i < input.length) {
  974.                 enc1 = this._keyStr.indexOf(input.charAt(i++));
  975.                 enc2 = this._keyStr.indexOf(input.charAt(i++));
  976.                 enc3 = this._keyStr.indexOf(input.charAt(i++));
  977.                 enc4 = this._keyStr.indexOf(input.charAt(i++));
  978.                 chr1 = (enc1 << 2) | (enc2 >> 4);
  979.                 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  980.                 chr3 = ((enc3 & 3) << 6) | enc4;
  981.                 output = output + String.fromCharCode(chr1);
  982.                 if (enc3 != 64) {
  983.                     output = output + String.fromCharCode(chr2);
  984.                 }
  985.                 if (enc4 != 64) {
  986.                     output = output + String.fromCharCode(chr3);
  987.                 }
  988.             }
  989.             output = Base64._utf8_decode(output);
  990.             return output;
  991.         },
  992.      
  993.         // private method for UTF-8 encoding
  994.         _utf8_encode : function (string) {
  995.             string = string.replace(/\r\n/g,"\n");
  996.             var utftext = "";
  997.             for (var n = 0; n < string.length; n++) {
  998.                 var c = string.charCodeAt(n);
  999.                 if (c < 128) {
  1000.                     utftext += String.fromCharCode(c);
  1001.                 }
  1002.                 else if((c > 127) && (c < 2048)) {
  1003.                     utftext += String.fromCharCode((c >> 6) | 192);
  1004.                     utftext += String.fromCharCode((c & 63) | 128);
  1005.                 }
  1006.                 else {
  1007.                     utftext += String.fromCharCode((c >> 12) | 224);
  1008.                     utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  1009.                     utftext += String.fromCharCode((c & 63) | 128);
  1010.                 }
  1011.             }
  1012.             return utftext;
  1013.         },
  1014.         // private method for UTF-8 decoding
  1015.         _utf8_decode : function (utftext) {
  1016.             var string = "";
  1017.             var i = 0;
  1018.             var c = c1 = c2 = 0;
  1019.             while ( i < utftext.length ) {
  1020.                 c = utftext.charCodeAt(i);
  1021.                 if (c < 128) {
  1022.                     string += String.fromCharCode(c);
  1023.                     i++;
  1024.                 }
  1025.                 else if((c > 191) && (c < 224)) {
  1026.                     c2 = utftext.charCodeAt(i+1);
  1027.                     string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  1028.                     i += 2;
  1029.                 }
  1030.                 else {
  1031.                     c2 = utftext.charCodeAt(i+1);
  1032.                     c3 = utftext.charCodeAt(i+2);
  1033.                     string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  1034.                     i += 3;
  1035.                 }
  1036.             }
  1037.             return string;
  1038.         }
  1039. }
  1040.  
  1041. UtilService.prototype.base64Encode = function(text) {
  1042.     return Base64.encode(text);
  1043. }
  1044.  
  1045. UtilService.prototype.base64Decode = function(text) {
  1046.     return Base64.decode(text);
  1047. }
  1048.  
  1049. UtilService.prototype.migratePasswords=function() {
  1050.     var prefService=Components.classes["@mozilla.org/preferences-service;1"]
  1051.                                        .getService(Components.interfaces.nsIPrefService);
  1052.     var pref=prefService.getBranch("dwhelper.");
  1053.     if(pref.getBoolPref("passwords-migrated")==true) {
  1054.         return true;
  1055.     }
  1056.     try {
  1057.         var mp3tunesPw=pref.getCharPref("mp3tunes.password");
  1058.         if(mp3tunesPw.length>0) {
  1059.             this.doSetPassword("mp3tunes",mp3tunesPw);
  1060.             pref.setCharPref("mp3tunes.password","");
  1061.         }
  1062.         var twitterPw=pref.getCharPref("twitter.password");
  1063.         if(twitterPw.length>0) {
  1064.             this.doSetPassword("twitter",this.base64Decode(twitterPw));
  1065.             pref.setCharPref("twitter.password","");
  1066.         }
  1067.         pref.setBoolPref("passwords-migrated",true);
  1068.         return true;
  1069.     } catch(e) {
  1070.         dump("!!! [Core] migratePasswords: "+e+"\n");
  1071.     }
  1072.     return false;
  1073. }
  1074.  
  1075. UtilService.prototype.getPassword = function(service) {
  1076.     if(!this.migratePasswords())
  1077.         return null;
  1078.     return this.doGetPassword(service);
  1079. }
  1080.     
  1081. UtilService.prototype.doGetPassword = function(service) {
  1082.     if(Components.classes["@mozilla.org/login-manager;1"]) {
  1083.         var loginMgr = Components.classes["@mozilla.org/login-manager;1"]
  1084.                                           .getService(Components.interfaces.nsILoginManager);
  1085.         var logins = loginMgr.findLogins({}, service+".password-manager.downloadhelper.net", null, 'downloadhelper');
  1086.         for (var i = 0; i < logins.length; i++) {
  1087.            if (logins[i].username == 'downloadhelper') {
  1088.               return logins[i].password;
  1089.            }
  1090.         }
  1091.         return null;
  1092.     } else {
  1093.         var prefService=Components.classes["@mozilla.org/preferences-service;1"]
  1094.                                            .getService(Components.interfaces.nsIPrefService);
  1095.         var pref=prefService.getBranch("dwhelper.");
  1096.         try {
  1097.             return this.base64Decode(pref.getCharPref("password-manager."+service));
  1098.         } catch(e) {
  1099.             return null;
  1100.         }
  1101.     }
  1102. }
  1103.  
  1104. UtilService.prototype.setPassword = function(service,password) {
  1105.     if(!this.migratePasswords())
  1106.         return;
  1107.     this.doSetPassword(service,password);
  1108. }
  1109.  
  1110. UtilService.prototype.doSetPassword = function(service,password) {
  1111.     if(Components.classes["@mozilla.org/login-manager;1"]) {
  1112.         var loginMgr = Components.classes["@mozilla.org/login-manager;1"]
  1113.                                           .getService(Components.interfaces.nsILoginManager);
  1114.         var logins = loginMgr.findLogins({}, service+".password-manager.downloadhelper.net", null, 'downloadhelper');
  1115.         for (var i = 0; i < logins.length; i++) {
  1116.             loginMgr.removeLogin(logins[i]);
  1117.         }
  1118.         var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
  1119.                 Components.interfaces.nsILoginInfo,
  1120.                 "init");
  1121.         var loginInfo = new nsLoginInfo(service+'.password-manager.downloadhelper.net', null, 'downloadhelper', 'downloadhelper', password, "", "");
  1122.         try {
  1123.             loginMgr.addLogin(loginInfo);
  1124.         } catch(e) {
  1125.             dump("!!! [Util] doSetPassword('"+service+","+password+"): addLogin: "+e1+"\n");
  1126.         }
  1127.     } else {
  1128.         var prefService=Components.classes["@mozilla.org/preferences-service;1"]
  1129.                                            .getService(Components.interfaces.nsIPrefService);
  1130.         var pref=prefService.getBranch("dwhelper.");
  1131.         pref.setCharPref("password-manager."+service,this.base64Encode(password));
  1132.     }
  1133. }
  1134.  
  1135. UtilService.prototype.priorTo19 = function() {
  1136.     var browserCompatible=false;
  1137.     try {
  1138.         var browserVersion=Components.classes["@mozilla.org/xre/app-info;1"]
  1139.                                                .getService(Components.interfaces.nsIXULAppInfo).platformVersion;
  1140.         var comparator=Components.classes["@mozilla.org/xpcom/version-comparator;1"]
  1141.                                           .getService(Components.interfaces.nsIVersionComparator);
  1142.         if(comparator.compare(browserVersion,"1.9")>=0)
  1143.             browserCompatible=true;
  1144.     } catch(e) {}
  1145.     return !browserCompatible;
  1146. }
  1147.  
  1148. UtilService.prototype.QueryInterface = function(iid) {
  1149.     if (!iid.equals(Components.interfaces.nsISupports) && 
  1150.         !iid.equals(Components.interfaces.dhIUtilService)) {
  1151.             //dump("UtilService: requested invalid interface "+iid+"\n");
  1152.             throw Components.results.NS_ERROR_NO_INTERFACE;
  1153.         }
  1154.     return this;
  1155. }
  1156.  
  1157. var vUtilServiceModule = {
  1158.     firstTime: true,
  1159.     
  1160.     /*
  1161.      * RegisterSelf is called at registration time (component installation
  1162.      * or the only-until-release startup autoregistration) and is responsible
  1163.      * for notifying the component manager of all components implemented in
  1164.      * this module.  The fileSpec, location and type parameters are mostly
  1165.      * opaque, and should be passed on to the registerComponent call
  1166.      * unmolested.
  1167.      */
  1168.     registerSelf: function (compMgr, fileSpec, location, type) {
  1169.  
  1170.         if (this.firstTime) {
  1171.             this.firstTime = false;
  1172.             throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  1173.         }
  1174.         compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  1175.         compMgr.registerFactoryLocation(NS_UTIL_SERVICE_CID,
  1176.                                         "UtilService",
  1177.                                         NS_UTIL_SERVICE_PROG_ID, 
  1178.                                         fileSpec,
  1179.                                         location,
  1180.                                         type);
  1181.     },
  1182.  
  1183.     unregisterSelf: function(compMgr, fileSpec, location) {
  1184.         compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  1185.         compMgr.unregisterFactoryLocation(NS_UTIL_SERVICE_CID, fileSpec);
  1186.     },
  1187.  
  1188.     /*
  1189.      * The GetClassObject method is responsible for producing Factory and
  1190.      * SingletonFactory objects (the latter are specialized for services).
  1191.      */
  1192.     getClassObject: function (compMgr, cid, iid) {
  1193.         if (!cid.equals(NS_UTIL_SERVICE_CID)) {
  1194.             throw Components.results.NS_ERROR_NO_INTERFACE;
  1195.         }
  1196.  
  1197.         if (!iid.equals(Components.interfaces.nsIFactory)) {
  1198.             throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  1199.         }
  1200.  
  1201.         return this.vUtilServiceFactory;
  1202.     },
  1203.  
  1204.     /* factory object */
  1205.     vUtilServiceFactory: {
  1206.         /*
  1207.          * Construct an instance of the interface specified by iid, possibly
  1208.          * aggregating it with the provided outer.  (If you don't know what
  1209.          * aggregation is all about, you don't need to.  It reduces even the
  1210.          * mightiest of XPCOM warriors to snivelling cowards.)
  1211.          */
  1212.         createInstance: function (outer, iid) {
  1213.             if (outer != null) {
  1214.                 throw Components.results.NS_ERROR_NO_AGGREGATION;
  1215.             }
  1216.  
  1217.             if(Node==null)
  1218.                 Node=Components.interfaces.nsIDOMNode;
  1219.  
  1220.             if(XPathResult==null)
  1221.                 XPathResult=Components.interfaces.nsIDOMXPathResult;
  1222.     
  1223.             return (new UtilService()).QueryInterface(iid);
  1224.         }
  1225.     },
  1226.  
  1227.     /*
  1228.      * The canUnload method signals that the component is about to be unloaded.
  1229.      * C++ components can return false to indicate that they don't wish to be
  1230.      * unloaded, but the return value from JS components' canUnload is ignored:
  1231.      * mark-and-sweep will keep everything around until it's no longer in use,
  1232.      * making unconditional ``unload'' safe.
  1233.      *
  1234.      * You still need to provide a (likely useless) canUnload method, though:
  1235.      * it's part of the nsIModule interface contract, and the JS loader _will_
  1236.      * call it.
  1237.      */
  1238.     canUnload: function(compMgr) {
  1239.         return true;
  1240.     }
  1241. };
  1242.  
  1243. function NSGetModule(compMgr, fileSpec) {
  1244.     return vUtilServiceModule;
  1245. }
  1246.